作用域
作用:读、写
域:空间、范围、区域
----JS解析器-----
script 全局变量、全局函数。【自上而下】
函数域 局部变量、局部函数。【自里而外】
<script>
alert(a);
var a = 1;
function fn1(){
alert(2);
}
</script>
1)JS的预解析
找一些东西 【var function 参数】
1、var a = 1;
找到 var a,设置成 a = undefined。不读取后边的 = 1。
【所有的变量,在正式运行代码之前,都赋值一个值,undefined】
2、fn1 = function fn1() { alert(2); }
【所有的函数,在正式运行代码之前,都是整个函数块,不运行里边的内容】
**预解析机制
遇到重名的:只留一个,留下不留上。变量和函数重名,不论上下,留函数。
2)逐行解读代码
1、alert(a); //undefined
因为JS的预解析中,var a = undefined。
【开始解读代码,从JS的预解析中去找】
2、var a = 1; //通过表达式将a变成1
表达式: = - + * / % ++ -- ! 参数
【能改变值得都是表达式,表达式能修改预解析的值】
3、function fn1(){} //函数,没被调用,不会执行内部代码
<script>
var a = 1;
alert(b); //error: not a defined
</script>
<script>
alert(a); //1
var b = 2;
</script>
//script 自上而下,执行完script1,再执行script2。
//script1中使用,自己未定义,在script2中定义的变量,会报错
//script2中使用,script1中定义的变量,可以使用。
<script>
var a = 1;
function fn1 () {
alert(a); //1
}
fn1();
</script>
1、script预解析【var function 参数】
var a = undefined
function fn1(){}
2、逐行解读代码
var a = 1; //表达式
function fn1(){} //不执行
fn1() //函数调用
2.1 预解析 【var function 参数】
2.2逐行解读代码
3、继续逐行解读全局代码
function(){} //运行由里到外
作用域链
子级作用域(函数)没有找到 【var function 参数】,回到父级作用域找到【var function 参数】
逐行解析代码,执行表达式会更改 父级【var function 参数】内容
子级作用域(函数)找到【参数】,进行预解析 = var 参数(局部变量)
<script>
var a = 2;
// function test (var a){}
function test (a){
alert(a); //1
}
test(1);
</script>
1、有传参的情况下,会默认在子级函数作用域,解析 var a = undefined
2、逐行解读代码
var = 参数 //执行表达式,不传参就是undefined
alert(a) //1 先在当前作用域找a,如果有就直接使用,如果没有就去父级作用域找。【由里而外】
JS没有块级作用域的概念,会解析if(){} for(){}里边的var。并添加到当前环境中。不会被销毁
FF不能对if(){}, for(){} 里边function进行预解析,兼容性
<script>
function add(num1, num2) {
var sum = num1 + num2;
return sum;
}
var result = add(10, 20); //30
alert(sum); //由于sum不是全局变量,会报错
function add2(num1, num2) {
sum = num1 + num2;
return sum;
}
var result = add2(10, 20); //30
alert(sum); //30 因为使用了匿名函数,变成了全局变量
</script>
在子级作用域中,使用匿名变量,会加载到全局作用域中。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。